﻿#include <iostream>
#include <fstream>
#include <vector>
#include <algorithm>
#include <ctime>
#include <map>
#include <sstream>
#include <iomanip>

using namespace std;

// 车次信息结构体
struct Train {
    string trainNumber;  // 车次
    string departureTime;  // 发车时间
    string startStation;  // 起点站
    string endStation;  // 终点站
    int travelTime;  // 行车时间（分钟）
    int capacity;  // 额定载量
    int remainingTickets;  // 余票数量
};

// 全局变量
vector<Train> trains;  // 存储所有车次信息
map<string, string> bookedTickets;  // 存储购票信息（用户名 -> 车次）

// 管理员密码
const string ADMIN_PASSWORD = "admin123";

// 加载车次信息
void loadSchedule() {
    ifstream file("schedule.dat");
    if (file.is_open()) {
        string line;
        while (getline(file, line)) {
            Train train;
            stringstream ss(line);
            getline(ss, train.trainNumber, ',');
            getline(ss, train.departureTime, ',');
            getline(ss, train.startStation, ',');
            getline(ss, train.endStation, ',');
            ss >> train.travelTime;
            ss.ignore();
            ss >> train.capacity;
            ss.ignore();
            ss >> train.remainingTickets;
            trains.push_back(train);
        }
        file.close();
    }
}

// 保存车次信息
void saveSchedule() {
    ofstream file("schedule.dat");
    if (file.is_open()) {
        for (const Train &train : trains) {
            file << train.trainNumber << ","
                 << train.departureTime << ","
                 << train.startStation << ","
                 << train.endStation << ","
                 << train.travelTime << ","
                 << train.capacity << ","
                 << train.remainingTickets << "\n";
        }
        file.close();
    }
}

// 显示所有车次信息
void displayTrains() {
    time_t now = time(0);
    tm *currentTime = localtime(&now);
    cout << "车次\t发车时间\t起点站\t终点站\t行车时间\t额定载量\t余票数量\t状态\n";
    for (const Train &train : trains) {
        tm departureTm = {};
        strptime(train.departureTime.c_str(), "%Y-%m-%d %H:%M", &departureTm);
        time_t departureTime = mktime(&departureTm);
        string status = (now >= departureTime) ? "已发出" : "未发车";
        cout << train.trainNumber << "\t"
             << train.departureTime << "\t"
             << train.startStation << "\t"
             << train.endStation << "\t"
             << train.travelTime << "分钟\t"
             << train.capacity << "\t"
             << train.remainingTickets << "\t"
             << status << "\n";
    }
}

// 按车次号查询
void queryByTrainNumber(const string &trainNumber) {
    for (const Train &train : trains) {
        if (train.trainNumber == trainNumber) {
            cout << "车次: " << train.trainNumber << "\n"
                 << "发车时间: " << train.departureTime << "\n"
                 << "起点站: " << train.startStation << "\n"
                 << "终点站: " << train.endStation << "\n"
                 << "余票数量: " << train.remainingTickets << "\n";
            return;
        }
    }
    cout << "未找到该车次！\n";
}

// 按起点站和终点站查询
void queryByStations(const string &startStation, const string &endStation) {
    for (const Train &train : trains) {
        if (train.startStation == startStation && train.endStation == endStation) {
            cout << "车次: " << train.trainNumber << "\n"
                 << "发车时间: " << train.departureTime << "\n"
                 << "余票数量: " << train.remainingTickets << "\n";
        }
    }
}

// 按发车时间排序
void sortByDepartureTime() {
    sort(trains.begin(), trains.end(), [](const Train &a, const Train &b) {
        tm tmA = {}, tmB = {};
        strptime(a.departureTime.c_str(), "%Y-%m-%d %H:%M", &tmA);
        strptime(b.departureTime.c_str(), "%Y-%m-%d %H:%M", &tmB);
        return difftime(mktime(&tmA), mktime(&tmB)) < 0;
    });
    saveSchedule();
    cout << "已按发车时间排序并保存！\n";
}

// 售票功能
void sellTicket(const string &trainNumber, const string &username) {
    time_t now = time(0);
    for (Train &train : trains) {
        if (train.trainNumber == trainNumber) {
            tm departureTm = {};
            strptime(train.departureTime.c_str(), "%Y-%m-%d %H:%M", &departureTm);
            time_t departureTime = mktime(&departureTm);
            if (now >= departureTime) {
                cout << "该车次已发出，无法购票！\n";
                return;
            }
            if (train.remainingTickets <= 0) {
                cout << "余票不足，无法购票！\n";
                return;
            }
            if (bookedTickets.find(username) != bookedTickets.end()) {
                cout << "您已购买其他车次，无法重复购票！\n";
                return;
            }
            train.remainingTickets--;
            bookedTickets[username] = trainNumber;
            saveSchedule();
            cout << "购票成功！\n";
            return;
        }
    }
    cout << "未找到该车次！\n";
}

// 退票功能
void refundTicket(const string &trainNumber, const string &username) {
    time_t now = time(0);
    for (Train &train : trains) {
        if (train.trainNumber == trainNumber) {
            tm departureTm = {};
            strptime(train.departureTime.c_str(), "%Y-%m-%d %H:%M", &departureTm);
            time_t departureTime = mktime(&departureTm);
            if (now >= departureTime - 1800) {  // 发车前半小时内不可退票
                cout << "该车次即将发车，无法退票！\n";
                return;
            }
            if (bookedTickets.find(username) == bookedTickets.end()) {
                cout << "您未购买该车次，无法退票！\n";
                return;
            }
            train.remainingTickets++;
            bookedTickets.erase(username);
            saveSchedule();
            cout << "退票成功！\n";
            return;
        }
    }
    cout << "未找到该车次！\n";
}

// 主菜单
void showMenu(bool isAdmin) {
    cout << "========== 火车票务管理系统 ==========\n";
    if (isAdmin) {
        cout << "1. 录入车次信息\n";
        cout << "2. 修改车次信息\n";
        cout << "3. 删除车次信息\n";
    }
    cout << "4. 浏览所有车次信息\n";
    cout << "5. 按车次号查询\n";
    cout << "6. 按起点站和终点站查询\n";
    cout << "7. 按发车时间排序\n";
    cout << "8. 售票\n";
    cout << "9. 退票\n";
    cout << "10. 退出\n";
    cout << "请输入选项: ";
}

int main() {
    // 加载车次信息
    loadSchedule();

    // 登录验证
    bool isAdmin = false;
    cout << "请输入密码（普通用户直接按回车跳过）：";
    string password;
    getline(cin, password);
    if (password == ADMIN_PASSWORD) {
        isAdmin = true;
        cout << "管理员登录成功！\n";
    } else {
        cout << "普通用户登录成功！\n";
    }

    int choice;
    while (true) {
        showMenu(isAdmin);
        cin >> choice;
        cin.ignore();  // 清除输入缓冲区

        switch (choice) {
            case 1: {
                if (!isAdmin) {
                    cout << "无权限操作！\n";
                    break;
                }
                // 录入车次信息
                Train train;
                cout << "请输入车次号：";
                getline(cin, train.trainNumber);
                cout << "请输入发车时间（格式：yyyy-MM-dd HH:MM）：";
                getline(cin, train.departureTime);
                cout << "请输入起点站：";
                getline(cin, train.startStation);
                cout << "请输入终点站：";
                getline(cin, train.endStation);
                cout << "请输入行车时间（分钟）：";
                cin >> train.travelTime;
                cout << "请输入额定载量：";
                cin >> train.capacity;
                cout << "请输入余票数量：";
                cin >> train.remainingTickets;
                trains.push_back(train);
                saveSchedule();
                cout << "车次信息录入成功！\n";
                break;
            }
            case 2: {
                if (!isAdmin) {
                    cout << "无权限操作！\n";
                    break;
                }
                // 修改车次信息
                string trainNumber;
                cout << "请输入要修改的车次号：";
                getline(cin, trainNumber);
                for (Train &train : trains) {
                    if (train.trainNumber == trainNumber) {
                        cout << "请输入新的发车时间（格式：yyyy-MM-dd HH:MM）：";
                        getline(cin, train.departureTime);
                        cout << "请输入新的起点站：";
                        getline(cin, train.startStation);
                        cout << "请输入新的终点站：";
                        getline(cin, train.endStation);
                        cout << "请输入新的行车时间（分钟）：";
                        cin >> train.travelTime;
                        cout << "请输入新的额定载量：";
                        cin >> train.capacity;
                        cout << "请输入新的余票数量：";
                        cin >> train.remainingTickets;
                        saveSchedule();
                        cout << "车次信息修改成功！\n";
                        break;
                    }
                }
                cout << "未找到该车次！\n";
                break;
            }
            case 3: {
                if (!isAdmin) {
                    cout << "无权限操作！\n";
                    break;
                }
                // 删除车次信息
                string trainNumber;
                cout << "请输入要删除的车次号：";
                getline(cin, trainNumber);
                for (auto it = trains.begin(); it != trains.end(); ++it) {
                    if (it->trainNumber == trainNumber) {
                        trains.erase(it);
                        saveSchedule();
                        cout << "车次信息删除成功！\n";
                        break;
                    }
                }
                cout << "未找到该车次！\n";
                break;
            }
            case 4: {
                // 浏览所有车次信息
                displayTrains();
                break;
            }
            case 5: {
                // 按车次号查询
                string trainNumber;
                cout << "请输入车次号：";
                getline(cin, trainNumber);
                queryByTrainNumber(trainNumber);
                break;
            }
            case 6: {
                // 按起点站和终点站查询
                string startStation, endStation;
                cout << "请输入起点站：";
                getline(cin, startStation);
                cout << "请输入终点站：";
                getline(cin, endStation);
                queryByStations(startStation, endStation);
                break;
            }
            case 7: {
                // 按发车时间排序
                sortByDepartureTime();
                break;
            }
            case 8: {
                // 售票
                string trainNumber, username;
                cout << "请输入车次号：";
                getline(cin, trainNumber);
                cout << "请输入用户名：";
                getline(cin, username);
                sellTicket(trainNumber, username);
                break;
            }
            case 9: {
                // 退票
                string trainNumber, username;
                cout << "请输入车次号：";
                getline(cin, trainNumber);
                cout << "请输入用户名：";
                getline(cin, username);
                refundTicket(trainNumber, username);
                break;
            }
            case 10: {
                // 退出
                cout << "感谢使用火车票务管理系统！\n";
                return 0;
            }
            default: {
                cout << "无效的选项，请重新输入！\n";
                break;
            }
        }
    }

    return 0;
}